<template>
    <div id="app" class="containers" ref="bpmnContainer">
        <div class="my-toolbar">
            <el-button-group>
                <!--                <el-button type="primary" size="mini" @click="previewTemp">预览</el-button>-->
                <el-button type="success" size="mini" @click="handleZoom(0.1)">放大</el-button>
                <el-button type="warning" size="mini" @click="handleZoom(-0.1)">缩小</el-button>
                <el-button type="success" size="mini" @click="handleZoom(0)">还原</el-button>
                <el-button type="primary" size="mini" @click="handleUndo">后退</el-button>
                <el-button type="success" size="mini" @click="handleRedo">前进</el-button>
                <el-button type="warning" size="mini" @click="handleDownload">下载</el-button>
                <el-upload
                        style="display: inline-block;"
                        :file-list="fileList"
                        class="upload-demo"
                        action=""
                        :auto-upload="false"
                        :show-file-list="false"
                        :on-change="handleOnchangeFile"
                        :on-remove="handleRemove"
                        :before-upload="beforeUpload"
                        :before-remove="beforeRemove"
                >
                    <el-button type="danger" size="mini">导入</el-button>
                </el-upload>
            </el-button-group>
            <el-select v-model="routingCfgValue" placeholder="请选择" @change="changeFlow">
                <el-option
                        v-for="item in routingCfgData"
                        :key="item.SegmentCode"
                        :label="item.SegmentName"
                        :value="item.SegmentCode"
                >
                </el-option>
            </el-select>
        </div>
        <div ref="palette"></div>
        <div class="canvas" ref="canvas"></div>

        <prop-panel :bpmn-modeler="bpmnModeler" :activity-info="selectActivety"></prop-panel>
    </div>
</template>

<script>
    import BpmnModeler from 'bpmn-js/lib/Modeler';
    import customModule from '@/custom/palette-all';
    import customRenderer from '@/custom/renderer';
    import minimapModule from 'diagram-js-minimap';
    import entries from '@/custom/palette-all/paletteEntries';
    import jsonData from '/json/lineconfig.json';
    import etlExtension from '@/custom/palette-all/etl.json';
    import propPanel from '@/components/PropPanel.vue';
    import ajax from '@/util/axiosUtil';
    import {
        append as svgAppend,
        attr as svgAttr,
        create as svgCreate
    } from 'tiny-svg';
    import { query as domQuery } from 'min-dom';

    export default {
        name: "indexpage",
        data() {
            return {
                bpmnModeler: null,
                scale: 1,
                fileList: [],
                selectActivety: null,
                routingCfgValue: '',
                routingCfgData: []
            };
        },
        components: {
            propPanel
        },
        mounted() {

            const canvas = this.$refs.canvas;
            const palette = this.$refs.palette

            const modules = BpmnModeler.prototype._modules
            const index = modules.findIndex(it => it.paletteProvider)
            modules.splice(index, 1)

            this.bpmnModeler = new BpmnModeler({
                container: canvas,
                // moddleExtensions: {camunda: camundaExtension},
                additionalModules: [
                    // 小地图
                    minimapModule,
                    // 自定义工具栏
                    customModule,
                    // 自定义渲染
                    customRenderer,
                ],
                // 工具栏容器
                paletteContainer: palette,
                // 工具栏配置及实现自定义渲染方法
                paletteEntries: entries,
                // 开启键盘快捷
                keyboard: {
                    bindTo: document
                },
                // 添加自定义元模型
                moddleExtensions: {
                    etl: etlExtension
                },
            });




            this.addModelerListener();
            this.initUI();
            this.loadData();
        },
        methods: {
            initUI() {
                var handleFileSelect = (e) => {
                    e.stopPropagation();
                    e.preventDefault();

                    var files = e.dataTransfer.files;
                    if (files.length > 0) {
                        var file = files[0];
                        if (this.chkImportFileExt(file.name)) {
                            var reader = new FileReader();
                            reader.readAsText(file);

                            reader.onload = (e) => {

                                var data = e.target.result;
                                this.bindModeler(data);
                            };
                        }
                    }
                }

                var handleDragOver = (e) => {
                    e.stopPropagation();
                    e.preventDefault();

                    e.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
                }

                this.$refs.bpmnContainer.addEventListener('dragover', handleDragOver, false);
                this.$refs.bpmnContainer.addEventListener('drop', handleFileSelect, false);
            },
            // 初始化自定义箭头
            initArrow (id) {
                const marker = svgCreate('marker')

                svgAttr(marker, {
                    id,
                    viewBox: '0 0 20 20',
                    refX: '11',
                    refY: '10',
                    markerWidth: '10',
                    markerHeight: '10',
                    orient: 'auto'
                })

                const path = svgCreate('path')

                svgAttr(path, {
                    d: 'M 1 5 L 11 10 L 1 15 Z',
                    style:
                        ' stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; '
                })

                const defs = domQuery('defs')
                svgAppend(marker, path)
                svgAppend(defs, marker)
            },
            addModelerListener() {
                const events = ['element.click', 'shape.move.end'];
                var elementRegistry = this.bpmnModeler.get('elementRegistry');
                events.forEach((event) => {
                    this.bpmnModeler.on(event, e => {
                        // console.log(event, e)
                        var activety = e.element ? elementRegistry.get(e.element.id) : e.shape;

                        console.log(activety);
                        // this.$nextTick(() => {
                        this.selectActivety = activety;
                        // })

                    })
                })
            },
            bindModeler(xml, callbakFunc) {
                this.bpmnModeler.importXML(xml).then(() => {
                    this.bpmnModeler.get('canvas').zoom('fit-viewport', 'auto');

                    // 打开 minimap, 默认不打开
                    // this.bpmnModeler.get('minimap').open();
                    // 初始化箭头
                    this.initArrow('sequenceflow-arrow-normal')
                    this.initArrow('sequenceflow-arrow-active')
                    if (callbakFunc) {
                        callbakFunc();
                    }

                }, err => {
                    if (err) {
                        this.$message.info('导入失败:' + err);
                    } else {
                        this.$message.success('导入成功');
                    }
                });
            },
            create() {
                this.bpmnModeler.createDiagram().then(() => {
                    this.bpmnModeler.get('canvas').zoom('fit-viewport', 'auto');
                });


            },
            previewTemp() {
                this.containerEl = document.getElementById('container');
                // 避免缓存，每次清一下
                this.bpmnModeler && this.bpmnModeler.destroy();
                this.scale = 1;
                this.bpmnModeler = new BpmnViewer({container: this.containerEl});
                const viewer = this.bpmnModeler;
                this.bpmnModeler.saveXML({format: true}, (err, data) => {
                    this.bpmnModeler.importXML(data, (err) => {
                        if (err) {
                            console.error(err);
                        } else {
                            // 只实现预览，核心代码以下两句足够
                            const canvas = viewer.get('canvas');
                            canvas.zoom('fit-viewport');
                            // 以下代码为：为节点注册鼠标悬浮事件
                            const eventBus = this.bpmnModeler.get('eventBus');
                            const overlays = this.bpmnModeler.get('overlays');
                            eventBus.on('element.hover', (e) => {
                                const $overlayHtml = jquery(` <div class="tipBox">
                    你好，我是悬浮框里的内容
                    </div>`);
                                overlays.add(e.element.id, {
                                    position: {top: e.element.height, left: 0},
                                    html: $overlayHtml
                                });
                            });
                            eventBus.on('element.out', () => {
                                overlays.clear();
                            });
                            //  注册悬浮事件结束
                        }
                    });
                });

            },
            handleZoom(radio) {
                const newScale = !radio ? 1.0 : this.scale + radio
                this.bpmnModeler.get('canvas').zoom(newScale)
                this.scale = newScale
            },
            handleRemove(file) {
                for (let i = 0; i < this.fileList.length; i++) {
                    if (file.name === this.fileList[i].name) {
                        this.fileList.splice(i, 1);
                    }
                }
            },
            chkImportFileExt(filename) {
                var fileExt = filename.replace(/.+\./, "");
                // if (['jpg','png','txt','zip', 'rar','pdf','doc','docx','xlsx'].indexOf(FileExt.toLowerCase()) === -1){
                //     this.$message({
                //         type: 'warning',
                //         message: '请上传后缀名为jpg、png、txt、pdf、doc、docx、xlsx、zip或rar的附件！'
                //     });
                //     return false;
                // }
                if (['bpmn', 'txt'].indexOf(fileExt.toLowerCase()) === -1) {
                    this.$message({
                        type: 'warning',
                        message: '请上传后缀名为bpmn或txt的文件！'
                    });
                    return false;
                }

                return true;
            },
            beforeUpload(file) {

                return this.chkImportFileExt(file.name);
            },
            beforeRemove(file) {
                return this.$confirm(`确定移除 ${file.name}？`);
            },
            // 后退
            handleUndo() {
                this.bpmnModeler.get('commandStack').undo();
            },
            // 前进
            handleRedo() {
                this.bpmnModeler.get('commandStack').redo();
            },
            handleDownload() {
                this.bpmnModeler.saveXML({format: true}, (err, data) => {
                    const dataTrack = 'bpmn';
                    const a = document.createElement('a');
                    const name = `diagram.${dataTrack}`;
                    a.setAttribute(
                        'href',
                        `data:application/bpmn20-xml;charset=UTF-8,${encodeURIComponent(data)}`
                    );
                    a.setAttribute('target', '_blank');
                    a.setAttribute('dataTrack', `diagram:download-${dataTrack}`);
                    a.setAttribute('download', name);
                    document.body.appendChild(a);
                    a.click();
                    document.body.removeChild(a);
                });
            },
            handleOnchangeFile(file) {
                const reader = new FileReader();
                reader.readAsText(file.raw);
                reader.onload = (event) => {
                    var data = event.target.result;
                    this.bindModeler(data);
                };
            },

            loadData() {
                this.create();
                // this.routingCfgData = jsonData.RoutingCfg.flatMap(q => q.Segments);

                // var body = {
                //     id: ''
                // }
                // ajax.post('/api/eplc/workflow/wf_definition/updateBpmn', JSON.stringify(body));
            },
            changeFlow(code) {
                var obj = jsonData.RoutingCfg.flatMap(q => q.Segments).find(q => q.SegmentCode == code);
                var arrName = obj.SegmentRouting.split('>');

                var stations = jsonData.Stations;

                const bpmnFactory = this.bpmnModeler.get('bpmnFactory'),
                    elementFactory = this.bpmnModeler.get('elementFactory'),
                    elementRegistry = this.bpmnModeler.get('elementRegistry'),
                    modeling = this.bpmnModeler.get('modeling');


                this.bpmnModeler.createDiagram().then(() => {
                    const process = elementRegistry.get('Process_1');

                    const startEvent = elementRegistry.get('StartEvent_1');

                    var prevActive = startEvent;
                    var x = 200, y = 200, i = 0;

                    arrName.forEach(code => {
                        stations.forEach(q => {
                            if (q.Name == code) {

                                const taskBusinessObject = bpmnFactory.create('bpmn:Task', {
                                    id: 'Task_' + q.Name,
                                    name: q.Name,
                                    info: q
                                });

                                const task = elementFactory.createShape({
                                    type: 'bpmn:Task',
                                    businessObject: taskBusinessObject
                                });

                                modeling.appendShape(prevActive, task, {x: x + i * 150, y: y + i * 50}, process);

                                prevActive = task;
                                ++i;
                            }
                        })
                    })


                    this.bpmnModeler.get('canvas').zoom('fit-viewport', 'auto');
                    // this.addModelerListener();
                });


            }
        }

    }
</script>

<style lang="scss">


    html, body {
        padding: 0;
        margin: 0;
    }

    .containers {
        position: absolute;
        background-color: #ffffff;
        width: 100%;
        height: 100%;

        .my-toolbar {
            position: absolute;
            left: 100px;
            top: 12px;
            z-index: 2;
        }

        .canvas {
            width: 100%;
            height: 100%;
        }

        .bjs-powered-by {
            display: none;
        }

        a:link {
            text-decoration: none;
        }


        .buttons {
            position: fixed;
            bottom: 20px;
            left: 20px;

            padding: 0;
            margin: 0;
            list-style: none;

            > li {
                display: inline-block;
                margin-right: 10px;

                > a {
                    background: #DDD;
                    border: solid 1px #666;
                    display: inline-block;
                    padding: 5px;
                }
            }
        }

        .tipBox {
            width: 200px;
            background: #fff;
            border-radius: 4px;
            border: 1px solid #ebeef5;
            padding: 12px;
        }
    }
</style>
